I sometimes think people only believe apple is good at user interaction design because their marketing is very convincing toward that point.
Admittedly, it is less of a steaming pile of crap than anything Microsoft has ever done. But, that only started when Apple tossed their whole foundation out the window and used some open-source code to rebuild their system on a solid base. Not building code on top of an OS written by a 22-yr-old intern is usually a good plan.
They've still managed to make things make no sense e.g. by making the default filesystem case insensitive without bothering to make `find` behave accordingly. The logical thing would have been to simply make case-insensitive search be the default in the finder, with maybe a "training wheels" setting that re-cases your filenames when you try to save something in the UI and/or warns you about potentially-confusing naming conflicts. This "65 == 97" junk just doesn't make any sense.
Of course, I've uttered "That doesn't make any sense" while looking at a great many pieces of software. All software sucks. This is why I prefer to be looking at source code.
The situation isn't going to get any better without paying serious attention to our infrastructure. We're in a sad state when it takes death to make us realize what we've been neglecting. The hyper-consumerism and downward price pressure just perpetuate this. But I digress -- the parallels between lack of investment in parrot and aging bridges are a topic for another day.
If you know anything about fracture mechanics, you understand "the devil is in the details" at a whole new level. A flaw in an 1/8" weld can easily lead to catastrophic failure of an entire 800' assembly, especially under repeated, oscillating load.
So, yes, I'm harping on low-level stuff here. But if we can't get basic things like the sentence structure (or even the words) right, how are we ever going to be able to effectively use something as complicated as a metaphor?
For instance, when you describe something as "it's like a ...", that is a simile, not a metaphor. A metaphor is something much more powerful and subtle. It is painting a picture of what you want to convey, rather than bluntly shouting "it's just like a folder in your filing cabinet!" (and shouting more loudly to make yourself more clear.)
At the even lower level, we've totally butchered the jargon with things like 'prototype' and even 'type'.
Humans are logic engines, though some have faultier or slower engines than others (mine usually runs too hot when negated logic requires me to keep 2-3 buffers in play.) The users will form some sort of logical model of what the software does, and the program's responsibility is to be logically consistent. If the user has the wrong model, it should be obvious.
The UI is an abstraction in the same way that the API is an abstraction. However, the UI is a much higher-level abstraction, so I'll refer you to any *::Simple module on CPAN for the potential pitfalls. You lose power, correctness, or understanding -- depending on how the abstraction was constructed.
Of course, rubbing herring on the fox doesn't help. If you try to treat the user like an idiot, they'll feel like one because you're giving them false information. How we name our menus and options is really important because I am the only person in the world who reads documentation (if you disagree, then I heartily welcome you to my very elite club -- there's room for two.)
Yes, it would do us all some good to brave the sunlight and go heft an object in the real world to consider its affordances, how it is used, and how it works, etc. But, I'm not sure we're ready for that much of a metaphor yet (though I'll ask you to please note that the hood on your car is not welded shut.) I think the root of understanding design lies in physics. You cannot build an object in the real world which defies the laws of physics. Most humans intuitively understand conservation of mass/energy, the direction of gravity, etc. Yet we construct elaborate and shaky metaphors for our software supported by layers and layers of internally inconsistent metaphors supported by layers and layers of arbitrarily complicated code (much of which exists solely to apologize for the presence of the rest.)
Back to api's... it's worth noting that most api design is not very good. But there's that word "interface" again. maybe we discounted it as meaning "interface between software", but the api is the programmer's interface into your abstraction (and this is why the c++/java "living room ... has a shotgun" approach doesn't work.) Interface is a form of communication, and effective communication isn't easy (especially when you don't hear the person on the other end of time and space swearing at you.)
We really need to get our code to be logically consistent all the way down. If you're thinking as the coder "it's easier to code that feature this way", and that is in opposition to the user model, something is wrong with the code. If you think the user's demands for relations don't work with your SQL schema, something is wrong with your perception of their needs or your schema.
And, when you calculate sales tax, you don't need an if()/else to address the case of there being no tax. $total = (1+$tax)*$subtotal is sufficient. You know, math.